﻿// Doctrine CC
// Holy/Prot/Ret
// by fiftypence
//
// Please note if you wish to reuse code found in any function
// within the Doctrine namespace, credit should be given to
// both the CC and CC author in your release thread.
// It is only fair.
//
// Thank you.

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Drawing;

using Styx;
using Styx.Combat.CombatRoutine;
using Styx.Helpers;
using Styx.Logic;
using Styx.Logic.Combat;
using Styx.Logic.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;

using Doctrine.Talents;

using CommonBehaviors.Actions;
using TreeSharp;
using Action = TreeSharp.Action;

namespace Doctrine
{
    partial class Paladin : CombatRoutine
    {
        #region Combat composites

        private Composite BuildLowLevelCombatBehavior()
        {
            return new Action(ret => Logging.Write(Color.Orange, "Low level combat is currently not supported."));
        }

        private Composite BuildHolyCombatBehavior()
        {
            return new Action(ret => Logging.Write(Color.Orange, "Holy combat is currently not supported."));
        }

        private Composite BuildProtCombatBehavior()
        {
            return new Decorator(ret => Me.CurrentTarget != null && !Me.Mounted,
                new PrioritySelector(
                    AutoAttack(),

                    new Decorator(ret => ShouldWeTaunt(),
                        new Action()
                    ),

                    CastHealOrProtect("Lay on Hands",              ret => Me.HealthPercent <= 15
                                                                          && SpellCooldown("Ardent Defender") > 0),
                    CastHealOrProtect("Ardent Defender",           ret => Me.HealthPercent <= 30),
                    CastHealOrProtect("Guardian of Ancient Kings", ret => Me.HealthPercent <= 60),
                    CastHealOrProtect("Holy Shield",               ret => Me.HealthPercent <= 95),
                    CastHealOrProtect("Divine Protection",         ret => Me.HealthPercent <= 95
                                                                          && SpellCooldown("Holy Shield") > 0),

                    new Decorator(ret => EnemyUnits.Count >= 2 && !IsTargetBoss() && ShouldWeAoe(),
                        new PrioritySelector(
                            CastSpell("Inquisition", ret => PlayerBuffTimeLeft("Inquisition") < 3 &&
                                                            Me.CurrentHolyPower == 3),
                            CastSpell("Hammer of the Righteous"),
                            CastSpell("Avenger's Shield"),
                            CastSpell("Holy Wrath"),
                            CastSpell("Judgement")
                        )
                    ),

                    new Decorator(ret => EnemyUnits.Count >= 2 && !ShouldWeAoe(),
                        new Action(delegate {

                            /* We are required to target the lowest
                             * threat unit here because we are in an
                             * AoE situation but we are unable to AoE
                             * due to crowd control.
                             * 
                             * Targetting the lowest threat ensures
                             * that we can keep AoE agro whilst still
                             * using our single-target rotation. */
                            
                            TargetLowestThreat();
                            return RunStatus.Failure; })
                    ),

                    new Decorator(ret => EnemyUnits.Count() < 2 || IsTargetBoss() || !ShouldWeAoe(),
                        new PrioritySelector(
                            CastSpell("Shield of the Righteous", ret => Me.CurrentHolyPower == 3),
                            CastSpell("Crusader Strike"),
                            CastSpell("Avenger's Shield"),
                            CastSpell("Hammer of Wrath",         ret => Me.CurrentTarget.HealthPercent < 20
                                                                        || PlayerHasBuff("Avenging Wrath")),
                            CastSpell("Judgement")
                        )
                    )
                )
            );
        }

        private Composite BuildRetCombatBehavior()
        {
            return new Decorator(ret => Me.CurrentTarget != null && !Me.Mounted,
                new PrioritySelector(
                    new Decorator(ret => SpellCooldown("Crusader Strike") > 0.5 || Me.CurrentHolyPower == 3,
                        new PrioritySelector(
                            AutoAttack(),

                            CastCooldown("Guardian of Ancient Kings", ret => IsTargetBoss() && PlayerBuffTimeLeft("Inquisition") > 20 &&
                                                                             (SpellCooldown("Zealotry") > 60 || SpellCooldown("Zealotry") < 10)),
                            CastCooldown("Zealotry",                  ret => IsTargetBoss() && 
                                                                             (Me.CurrentHolyPower == 3 || PlayerHasBuff("Divine Purpose")) &&
                                                                             PlayerBuffTimeLeft("Guardian of Ancient Kings") <= 20 &&
                                                                             SpellCooldown("Guardian of Ancient Kings") >= 15),
                            CastCooldown("Avenging Wrath",            ret => PlayerHasBuff("Zealotry")),

                            CastSpell("Inquisition",        ret => PlayerBuffTimeLeft("Inquisition") < 5 &&
                                                                   (Me.CurrentHolyPower == 3 || PlayerHasBuff("Divine Purpose"))),
                            CastSpell("Hammer of Wrath",    ret => Me.CurrentTarget.HealthPercent < 20 ||
                                                                   PlayerHasBuff("Avenging Wrath")),
                            CastSpell("Exorcism",           ret => PlayerHasBuff("The Art of War")),
                            CastSpell("Templar's Verdict",  ret => Me.CurrentHolyPower == 3 || PlayerHasBuff("Divine Purpose")),
                            CastSpell("Judgement"),
                            CastSpell("Holy Wrath",         ret => ShouldWeAoe() && Me.ManaPercent > 35),
                            CastSpell("Consecration",       ret => ShouldWeAoe() && Me.ManaPercent > 85),
                            CastSpell("Divine Plea",        ret => Me.ManaPercent <= 90)
                        )
                    ),

                    CastSpell("Crusader Strike", ret => EnemyUnits.Count() < 4 || IsTargetBoss()),
                    CastSpell("Divine Storm")
                )
            );
        }

        #endregion

        #region Combat buff composites

        private Composite BuildLowLevelCombatBuffBehavior()
        {
            return new Action();
        }

        private Composite BuildHolyCombatBuffBehavior()
        {
            return new Action();
        }

        private Composite BuildProtCombatBuffBehavior()
        {
            return new Action();
        }

        private Composite BuildRetCombatBuffBehavior()
        {
            return new PrioritySelector(
                CastBuff("Seal of Truth", ret => !PlayerHasBuff("Seal of Truth") && EnemyUnits.Count() < 4),
                CastBuff("Seal of Righteousness", ret => !PlayerHasBuff("Seal of Righteousness") && EnemyUnits.Count() >= 4)
            );
        }

        #endregion

        #region Pre-combat buff composites

        private Composite BuildLowLevelPreCombatBuffBehavior()
        {
            return new Action();
        }

        private Composite BuildHolyPreCombatBuffBehavior()
        {
            return new Action();
        }

        private Composite BuildProtPreCombatBuffBehavior()
        {
            return new Action();
        }

        private Composite BuildRetPreCombatBuffBehavior()
        {
            return new PrioritySelector(
                CastBuff("Seal of Truth", ret => !PlayerHasBuff("Seal of Truth")),
                CastBuff("Blessing of Might", ret => !PlayerHasBuff("Blessing of Might"))
            );
        }

        #endregion

        #region Other composites (TO DO)

        private Composite BuildPullBehavior()
        {
            return new Action();
        }

        private Composite BuildMoveToTargetBehavior()
        {
            return new Action();
        }

        private Composite BuildRestBehavior()
        {
            return new Action();
        }

        private Composite BuildHealBehavior()
        {
            return new Action();
        }

        #endregion
    }
}